/*
	Exemplos para compreendimento da função: listen
	Não tem o foco de compilação
*/

//	cabeçalhos:
#include <sys/types.h>
#include <sys/socket.h>

//	protótipos:
int listen(int sockfd, int backlog); 
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 
           
//	explicação :
/*
	[Usaremos no servidor]
	Listen: utilizado antes do accept, escuta conexões.
		Parâmetros:
		- sofckfd:	file descriptor retornado pela função socket()
		- backlog:	número de conexões permitido na fila de entrada
		Retorna: -1 em caso de erro.
		
	Accept: utilizado para aceitar uma conexão.
		Parâmetros:
		- sockfd:	file descriptor do socket que está na escuta.
		- *addr:	ponteiro para uma sockaddr_storage, informações sobre o
					socket que está conectando
		- *addrlen:	deve ser atribuido com sizeof(struct sockaddr_storage)
		
		Retorna: -1 em caso de erro.
*/

// exemplo:
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MYPORT "8080"  // the port users will be connecting to
#define BACKLOG 10     // how many pending connections queue will hold

int main() {
    struct sockaddr_storage their_addr;
    socklen_t addr_size;
    struct addrinfo hints, *res;
    int sockfd, new_fd;

    // limpa e inicializa a variável hints com as informações locais do servidor
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;     // fill in my IP for me
	
	// inicializa a variáve res
    getaddrinfo(NULL, MYPORT, &hints, &res);

    // make a socket, bind it, and listen on it:

    if( sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol) == -1) {
    	fprintf(stderr, "erro ao abrir o socket\n");
    }
    
    if( bind(sockfd, res->ai_addr, res->ai_addrlen) == -1 ) {
    	fprintf(stderr, "erro ao efetuar o bind\n");
    }
    
    if( listen(sockfd, BACKLOG) == -1 ) {
    	fprintf(stderr, "erro ao efetuar o listen\n");
    }

    // now accept an incoming connection:

    addr_size = sizeof their_addr;
    
    if( new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size) != -1 ) {
    	fprintf(stderr, "erro ao efetuar o accept\n");
    }

    // ready to communicate on socket descriptor new_fd!

 	//... continua o código   
    	
}
